\documentclass[a4paper, 11pt]{article}

\usepackage{amsmath}
\usepackage{fancyhdr}
\usepackage{layout}
\addtolength{\hoffset}{-1.0cm} \addtolength{\textwidth}{2cm}
\addtolength{\voffset}{-1.0cm} \addtolength{\textheight}{2cm}
\usepackage{appendix} %生成附录

\usepackage{cite}
\makeatletter
\def\@cite#1#2{\textsuperscript{[{#1\if@tempswa , #2\fi}]}}
\makeatother

\usepackage{appendix} %生成附录
\usepackage{flushend, cuted} %

\usepackage{indentfirst,latexsym,bm}
\usepackage{amsmath,amssymb,amsfonts}
\usepackage{pifont}
\usepackage{CJK}
\usepackage[rgb]{xcolor}
\usepackage[dvips]{graphicx}
\usepackage{subfigure}
\usepackage{url}
\usepackage{mathrsfs}
\usepackage{caption}
%\captionsetup{hypcap=true}%


\usepackage[dvipdfm, %,pdftex这里决定运行文件的方式不同
                  pdfstartview=FitH,
                  CJKbookmarks=true,
                  bookmarksnumbered=true,
                  bookmarksopen=true,
                  colorlinks, %注释掉此项则交叉引用为彩色边框(将colorlinks和pdfborder同时注释掉)
                  pdfborder=001, %注释掉此项则交叉引用为彩色边框
                  linkcolor=black,
                  anchorcolor=green,
                  citecolor=green
                  ]{hyperref}
\usepackage{footnotebackref}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \href{url}{text}                           %
% \url{url}                                  %
% \nolinkurl{url}                            %
% \hyperbaseurl{url}                         %
% \hyperimage{imageurl}{text}                %
% \hyperdef{category}{name}{text}            %
% \hyperref{url}{category}{name}{text}       %
% \hyperref{label}{text}                     %
% \hyperlink{name}{text}                     %
% \hypertarget{name}{text}                   %
% \phantomsection                            %
% \addcontentsline{toc}{chapter}{\indexname} %
% \printindex                                %
% \autoref{label}                            %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usepackage{listings}
\lstset{basicstyle=\footnotesize\ttfamily,
numbers=left,
numberstyle=\tiny,
keywordstyle=\color{blue!70}, commentstyle=\color{red!50!green!50!blue!50},
frame=shadowbox,
rulesepcolor=\color{red!20!green!20!blue!20},
escapeinside=``, xleftmargin=2em,xrightmargin=2em, aboveskip=1em,
language=C++, keywordstyle=\color{blue!70},  frame=shadowbox, rulesepcolor=\color{red!20!green!20!blue!20}
}
\lstset{extendedchars=false}


\setlength\mathsurround{3pt}
\setlength{\columnsep}{3em}          %设置分栏间隔
\setlength{\parindent}{2em}          %设置段首缩进量
\renewcommand{\baselinestretch}{1.2} %重设行距       \usepackage{graphicx}
\newcommand{\lishu}[1]{   \CJKfamily{li}   {#1}}   %隶书\renewcommand*\fuigurename{\KAI{图}}
\newcommand{\heiti}[1]{  \CJKfamily{hei}  {#1}}   %黑体
\newcommand{\kaiti}[1]{  \CJKfamily{kai}  {#1}}   %楷体\usepackage{cite}
\newcommand{\red}[1]{  \textcolor{red}  {#1}}   %红色\makeatletter
\newcommand{\blue}[1]{ \textcolor{blue} {#1}}   %蓝色\def\@cite#1#2{\textsuperscript{[{#1\if@tempswa , #2\fi}]}}
\newcommand{\green}[1]{\textcolor{green}{#1}}   %绿色\makeatother
%
\newcommand{\KAI}[1]{\begin{CJK*}{UTF8}{kai}{#1}\end{CJK*}}
\newcommand{\HEI}[1]{\begin{CJK*}{UTF8}{hei}{#1}\end{CJK*}}
\newcommand{\LI}[1]{\begin{CJK*}{UTF8}{li}{#1}\end{CJK*}}
\newcommand{\SONG}[1]{\begin{CJK*}{UTF8}{song}{#1}\end{CJK*}}
\newcommand{\YOU}[1]{\begin{CJK*}{UTF8}{you}{#1}\end{CJK*}}
\newcommand{\FSONG}[1]{\begin{CJK*}{UTF8}{fsong}{#1}\end{CJK*}}


%----------------------------------------------------------------
\vfuzz2pt % Don't report over-full v-boxes if over-edge is small
\hfuzz2pt % Don't report over-full h-boxes if over-edge is small


%%--------------------------------------------------
%% 图片文件路径
%%--------------------------------------------------


% MATH -----------------------------------------------------------
\DeclareMathOperator{\diag}{diag}
\DeclareMathOperator{\rank}{rank}
\DeclareMathOperator{\vecm}{vec}
\DeclareMathOperator{\vecs}{vecs}

\newcommand{\mfloor}[1]{ \left\lfloor {#1} \right\rfloor }
\newcommand{\mpair}[2]{ \left\langle {#1}, {#2} \right\rangle}


\renewcommand{\bf}[1]{\mathbf{#1}}
%\renewcommand{\vec}[1]{\bm{#1}}    %向量， 黑斜体
\newcommand{\mat}[1]{\bm{#1}}    %矩阵
\newcommand{\dif}{\mathrm{d}}
\newcommand{\diver}{\mathrm{div}}
\newcommand{\me} {\mathrm{e}}
\newcommand{\mi} {\mathrm{i}}

\newcommand{\vecmat}[1]{\vecm{\left( #1 \right)}}
\newcommand{\vecsmat}[1]{\vecs{\left( #1 \right)}}
\newcommand{\vecasym}[1]{[#1]_\times}   % antisymmetric matrix from a vector
\newcommand{\id} {\mathbbm{1}}   % identity operator
\newcommand{\fracode}[2]{\frac{\dif {#1}}{\dif {#2}}}         % ordinary differential operator
\newcommand{\fracpde}[2]{\frac{\partial {#1}}{\partial {#2}}} % partial differential operator
\newcommand{\fracpderow}[2]{\partial {#1}/\partial {#2}}
\newcommand{\fracoderow}[2]{\dif {#1}/\dif {#2}}
\newcommand{\fracpdemix}[3]{\frac{\partial^2 {#1}}{\partial {#2} \partial {#3}}}
\newcommand{\lap}[2]{\frac{\partial^2 {#1}}{\partial {#2}^2}}
\newcommand{\laprow}[2]{\partial^2 {#1}/\partial {#2}^2}
\newcommand{\secode}[2]{\frac{\dif^2 {#1}}{\dif {#2}^2}}
\newcommand{\set}[1]{\left\{ #1 \right\}}
\newcommand{\abs}[1]{\left| #1 \right|}
\newcommand{\absvec}[1]{\left| \bf{#1} \right|}
\newcommand{\ket}[1]{|#1 \rangle}
\newcommand{\bra}[1]{\langle #1 |}
\newcommand{\braket}[2]{ \langle #1 | #2 \rangle}
\newcommand{\norm}[1]{\lVert #1 \rVert}
\newcommand{\normF}[1]{{\parallel #1 \parallel}_\textrm{F}}
\newcommand{\tA}[1]{{#1}^\textsf{T}}
\newcommand{\inv}[1]{#1^{-1}}
\newcommand{\ginv}[1]{#1^+}    % Moore-Penrose (general) inverse
\newcommand{\tinv}[1]{{#1}^{-\textsf{T}}}


\newcommand{\ES}[3]{\mathbb{#1}^{{#2}\times {#3}}}               % Euclidean space
\newcommand{\PS}[3]{\mathbb{#1}^{{#2}\times{#3}}}      % projective space
% ----------------------------------------------------------------

\newcommand{\en}[1]{$\mathrm{#1}$}   

\begin{document}
\begin{CJK*}{UTF8}{song}



%%---------------------------------
%使用 Scale=0.5的图片而且点击图片标题能够回到引用图片的地方，需要和下面的\IREF命令配合使用(似乎和\par 有冲突，多图时别在前面用\par )
\newcommand{\IMGD}[3]{
\begin{figure}
\centering\includegraphics[scale=0.5]{#1}
\hyperref[#3totext]{\caption{#2}\label{#3}}

\end{figure}
}
%%---------------------------------
%IMaGe
\newcommand{\IMG}[4]{
\begin{figure}[h]
\centering\includegraphics[scale=#1]{#2}
\caption{#3}
\label{#4}
\end{figure}
}
%%---------------------------------
%使用点击文字到图片的超链接
\newcommand{\IREF}[1]{\hyperref[#1]{\KAI{图\ref{#1}}} \label{#1totext}}
%----------------------------------
%使用点击脚注到文字的超链接(目前无法使用)
\newcommand{\myfoot}[2]{\label{#1}\footnote{\hyperref[#1]{#2}}}

%%---------------------------------
%% 设置页眉与页脚
\pagestyle{fancy}
\fancyhead[LO,RE]{服务器的配置与\en{SSH}连接的使用} % clear all fields
\fancyhead[RO,LE]{ABSR-ER-No.006}   %  请设置正确的个人文档编号
%\fancyhead[LO,RE]{\CJKfamily{hei>} \bfseries \leftmark}
%\fancyfoot[LE,RO]{\thepage}
\fancyfoot[RO,LE]{中欧航空工程师学院}
\fancyfoot[LO,RE]{SIAE}
\renewcommand{\headrulewidth}{0.4pt}
\renewcommand{\footrulewidth}{0.4pt}

%%---------------------------------
% THEOREME
\newtheorem{thm}{\textcolor[rgb]{0.98,0.00,0.00}{定理}}
\newtheorem{cor}[thm]{\textcolor[rgb]{0.00,0.00,1.00}{推论}}
\newtheorem{lem}[thm]{\textcolor[rgb]{0.00,0.00,1.00}{引理}}
\newtheorem{prop}[thm]{\textcolor[rgb]{0.00,0.00,1.00}{性质}}
\newtheorem{prob}[thm]{\textcolor[rgb]{0.98,0.00,0.00}{问题}}
\newtheorem{conj}[thm]{\textcolor[rgb]{1.00,0.00,1.00}{猜想}}
\newtheorem{defn}[thm]{\textcolor[rgb]{0.44,0.00,0.87}{定义}}
\newtheorem{rem}[thm]{\textcolor[rgb]{1.00,0.50,0.25}{注记}}
\newtheorem{eg}[thm]{\textcolor[rgb]{0.00,0.00,1.00}{例}}%[chapter]

\renewcommand{\contentsname}{\hfil 目\quad 录}
\renewcommand{\figurename}{\kaiti{图}}
\renewcommand{\refname}{\kaiti{参考文献}}
\setcounter{figure}{0}


\title{\heiti{服务器的配置与\en{SSH}连接的使用\\ ABSR-ER-No.006}}
\author{\kaiti{王子昊}(Zi-Hao Wang)\\
               个人代号: ABSR-03,  电子邮件: zhwang0721@gmail.com }

\date{2015~年~02~月~17~日}


%%*************************************************
%%  打印 标题, 作者, 日期等内容
%%*************************************************
\maketitle       %
\tableofcontents
\pagenumbering{roman}
%%*************************************************
%% 显示内容目录
%%*************************************************
\newpage
\pagenumbering{arabic}
%%*************************************************
%% 正文部分
%%*************************************************
\section{说明}
\subsection{环境说明}
操作系统: Ubuntu 14.04.1\par 
$\mathrm{Python}$版本: 2.7.6\par 
$\mathrm{Apache}$版本: 2.4.7\par 
假设本机内网$\mathrm{IP}$地址: 10.1.46.3\par
假设用户名: \en{regis}
\subsection{本文档说明}
本文档介绍了两种在$\mathrm{Linux}$系统下架设$\mathrm{HTTP}$服务器的两种方法, 第一种是使用$\mathrm{Python}$自带模块构建的临时文件服务器, 另一种是使用$\mathrm{Apache}$搭建的服务器. 同时还介绍了使用$\mathrm{ssh}$命令远程登陆以及使用\en{sftp}远程传输文件的基本方法.
\section{准备工作}
\subsection{安装相关软件}
由于$\mathrm{Python}$模块系统自带, 只需安装$\mathrm{Apache}$即可:\par
\verb|$ sudo apt-get install apache2 |\par
远程登陆别的主机的软件\en{openssh}-\en{client}是系统自带的, 而如果你希望你的电脑能被远程登陆则需要安装\en{openssh}-\en{server}:\par
\verb|$ sudo apt-get install openssh-server |\par
\subsection{验证安装结果}
执行完成上面的命令后, 打开浏览器, 输入\,localhost\,或者\,127.0.0.1\,, 看到如下欢迎页面即说明\en{Apache}安装成功. \par
\IMG{0.15}{apache2default.eps}{Apache的默认页面}{}
如在环境说明中假设的自己用户名为\en{regis}, 则打开终端输入: \par
\verb|$ ssh regis@127.0.0.1|\par
得到类似如下输出:
\begin{verbatim}
  The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established.
  ECDSA key fingerprint is 04:69:10:57:da:57:9a:33:3c:51:dc:28:56:5d:d2:83.
  Are you sure you want to continue connecting (yes/no)? 
\end{verbatim}
\par 
则表示\en{openssh}-\en{server}安装成功.
\section{简易$\mathrm{HTTP}$文件服务器}
此方法非常简单, 系统自带的$\mathrm{Python}$模块即可实现功能. 考虑如下情况, 有几份文档需要分享给$\mathrm{ABS}$小组成员, 同在局域网内除了发邮件还有别的办法么? 答案是有的, 而且非常简单. 假设文档在\verb|~/Documents|文件夹下, 本机$\mathrm{IP}$地址同环境说明中的$\mathrm{IP}$地址, 执行这个下面这个$\mathrm{Python}$命令即可开启一个$\mathrm{HTTP}$服务器:\par
\verb|$ cd ~/Documents|\par
\verb|$ python -m SimpleHTTPServer 8008|\par 
参数\verb|-m| 表示运行$\mathrm{Python}$搜索路径下的模块, 后面的$8008$就是这个$\mathrm{HTTP}$服务器所在的端口号.
这样, 只要同在局域网中的人打开浏览器, 在地址栏输入你的$\mathrm{IP}$地址加端口号(即~10.1.46.3:8008~), 即可看到\verb|~/Documents|目录下的所有文件夹及文件, 点击即可打开或下载. 
注意:\begin{itemize}
\item 若不加端口号, 则默认为$8000$端口.
\item 服务器所在的根目录就在运行该命令的路径下. 例如我如果在\verb|~/Documents/LaTeX|下运行这个命令, 那么别人用浏览器打开时就只能看到\verb|~/Documents/LaTeX|以下的文件夹及文件, 而不能看到\verb|~/Documents|下的所有文件.
\item $\mathrm{HTTP}$协议并不适用于大文件的传输.
\end{itemize}

\section{$\mathrm{Apache~HTTP}$ 服务器}
由于我们已经成功安装了$\mathrm{Apache}$, 我们可以直接开始它的使用. 前面的那个简易的$\mathrm{HTTP}$文件服务器只是用到了$\mathrm{HTTP}$一部分, 而安装了$\mathrm{Apache}$的$\mathrm{HTTP}$服务器可以做很多事情, 比如, 在服务器上运行$\mathrm{Python}$应用.
\par
考虑下面这种情况: 我使用\en{Python}写了一个加法计算器, 想要让大家体验一下, 可是他们的电脑上没有\en{Python}环境, 怎么办呢? 有了$\mathrm{Apache}$我只需把这个程序稍作修改即可将它放在网上, 大家只要打开浏览器即可使用它. 下面就来做这个最简单的应用.
\subsection{$\mathrm{Apache}$的配置}
想让别人用网页访问的时候能够运行\en{Python}程序, 我们需要一个叫做通用网关接口的模块, 即\en{CGI}(Common~Gateway~Interface), 这个模块在安装$\mathrm{Apache}$的时候就自动装上了, 如果以后需要安装一些模块, 模块的包的命名规则如下: libapache2-mod-模块名, 那么安装也就只需要使用\en{apt}即可, 如我们想要安装单独支持\en{Python}的模块, 那么就使用下面这个命令进行安装:
\par
\verb|$ sudo apt-get install libapache2-mod-python|
\par
下面就是修改配置文件, 添加对\en{CGI}模块的支持:
\par
\verb|$ sudo vim /etc/apache2/apache2.conf|
\myfoot{zhuyi}{注意: 在\en{Debian}系统上, 这个文件名是\en{httpd.conf}.}
\\
将如下内容添加入刚刚打开的\en{apache2.conf}:
\begin{verbatim}
    #Load CGI module 加载CGI模块
    LoadModule cgi_module /usr/lib/apache2/modules/mod_cgi.so

    #Set the root directory 设置根目录
    DocumentRoot /var/www/html

    #Set the CGI directory 设置CGI目录
    ScriptAlias /cgi-bin/ /var/www/html/cgi-bin/

    #Add CGI file extension 添加CGI识别文件后缀
    AddHandler cgi-script .cgi .py .sh|
\end{verbatim}

再建立存放\en{CGI}程序的目录, 依照配置文件中的路径新建目录:
\par
\verb|$ sudo mkdir -p /var/www/html/cgi-bin/|\par
为了里面的程序可以正常运行, 修改次目录权限:
\par
\verb|$ sudo chmod 777 -R /var/www/html/cgi-bin/|
\subsection{修改原\en{Python}程序}
以下是原\en{Python}程序\en{my\_add.py}, 程序的目的是在得到两个输入以后把它们的和输出来:
\begin{verbatim}
    #!/usr/bin/python3
    #-*- coding:utf-8 -*-
    #获取数据字符串
    num_1_string = input("请输入第一个数\n")
    num_2_string = input("请输入第二个数\n")
    #把字符串转换为浮点类型数字
    num_1 = float(num_1_string)
    num_2 = float(num_2_string)
    #求和
    sum = num_1 + num_2
    #打印结果
    print("这两个数的和是:", sum)
\end{verbatim}
这是非常简单清晰的程序, 现在要对它做一下修改, 首先, 这个脚本程序在运行的时候是一个动态的过程: 输入第一个数后敲回车, 会让你输入第二个数. 我们要把这种动态的, 交互式的过程转化为静态的, 一次性的过程: 让用户在一个网页上把两个数据都给出, 然后提交这两个数据, 最后我们的\en{Python}再拿到这两个数据. 思路清楚了, 修改后的代码如下:
\begin{verbatim}
    #!/usr/bin/python3
    #-*- coding:utf-8 -*-
    #导入Python自带的CGI模块    
    import cgi
    #把之前的网页元素储存起来
    form = cgi.FieldStorage() 
    #获取数据字符串
    num_1_string = form.getvalue('first_num')
    num_2_string = form.getvalue('second_num')
    #把字符串转换为浮点类型数字
    num_1 = float(num_1_string)
    num_2 = float(num_2_string)
    #求和
    sum = num_1 + num_2
    #打印结果, 为了能被浏览器正确解析, 需要先打印一行固定格式的字符
    print("Content-type: text/html;charset=utf-8\n")
    print("这两个数的和是:", sum)
\end{verbatim}
将其命名为\en{my\_add\_web.py}, 拷贝到\verb|/var/www/html/cgi-bin/|目录下, 并修改权限:\par
\verb|sudo cp my_add_web.py /var/www/html/cgi-bin/|\par
\verb|sudo chmod 777 /var/www/html/cgi-bin/my_add_web.py|
\subsection{前端网页的编写}
从上面的程序可以知道, 在前端网页一定要把那两个被加的数字分别和\en{first\_num}, \en{second\_num}这两个变量绑定起来, 然后在点下按钮提交的时候调用我们刚才写的程序.
\par 这个简单的网页可以这样写:
\par
\begin{verbatim}
    <form action="/cgi-bin/my_add_web.py" method="get">
    输入第一个数: <input type="text" name="first_num">  <br />
    输入第二个数: <input type="text" name="second_num">  <br />
    <input type="submit" value="计算" />
    </form>
\end{verbatim}
把这个网页保存为\en{index.html}, 并拷贝到\verb|/var/www/html/|目录下:\par 
\verb|sudo cp index.html /var/www/html/index.html|
\subsection{最终结果}
如图所示:\par
\IMG{0.45}{my_add_web.eps}{简易的前端}{}
\par 
稍稍举一反三即可把更为复杂的桌面程序转化为\en{WEB}应用.
\section{\en{SSH}连接}
关于\en{SSH}连接有两个非常有用的命令:\en{ssh}和\en{sftp}. \en{ssh}可以理解为打开一个可以执行远程命令的终端, 而且数据的传输是被加密的. 而\en{sftp}主要负责远程文件传输. 说了这么多远程, 其实远程不一定很远, 考虑这样一个例子, 你身边的树莓派中运行着一个联网的\en{Ubuntu}系统, 你希望把刚刚学到的搭建HTTP服务器在它上面实践一下, 难道需要找齐鼠标, 键盘, 再配一台显示器才能操作么? 不, 只要它安装了\en{openssh}-\en{server}并且你知道它的\en{IP}以及用户名密码, 上面的一切都可以通过非接触式操作完成, 也就是远程操作完成. \par
\subsection{命令\en{ssh}的使用}
命令\en{ssh}的使用方法很简单, 格式如下:
\par
\verb|$ ssh 用户名@IP地址|\par
例如, 假设我们的树莓派的用户名是\en{pi}, \en{IP}是10.1.46.14, 那么这个命令就是这样:\par
\verb|$ ssh pi@10.1.46.14|\par
如果是第一次连接, 那么会有一段话问你是否信任这台主机, 输入\en{yes}按下回车, 就会要求你输入$10.1.46.14$那台主机上用户\en{pi}的密码, 输入正确的密码后, 就成功的登入那台树莓派的系统. 这时候你就可以像在本地一样一步一步的给它安装软件, 修改配置文件, 新建文件夹,修改权限了.
\subsection{命令\en{sftp}的使用}
服务器环境都配置好了, 网页和应用还需要重写一遍么? 当然不需要. 这时候我们只需要把本地的网页和程序上传到树莓派的相应路径下即可, 这时候就需要用到命令\en{sftp}.
格式与命令\en{ssh}一样, 例如我们要把本地写好的, 在\verb|/var/www/html/cgi-bin/|路径下的\verb|my_add_web.py|文件上传到树莓派的相同位置, 可以依次执行以下命令:
\par 
连接上树莓派
\par
\verb|$ sftp pi@10.1.46.14|\par 
切换本地目录到\verb|/var/www/html/cgi-bin/|路径下
\par
\verb|$ lcd /var/www/html/cgi-bin/|\par
切换树莓派的目录到\verb|/var/www/html/cgi-bin/|路径下
\par
\verb|$ cd /var/www/html/cgi-bin/|\par
查看本地的当前目录下有没有\verb|my_add_web.py|这个文件:
\par
\verb|$ lls|\par
上传\verb|my_add_web.py|文件
\par
\verb|$ put my_add_web.py|\par
查看树莓派的当前目录下有没有这个文件:
\par
\verb|$ ls|\par
可以发现对于命令\en{cd}, \en{ls}, 直接使用就是对远程登陆的系统操作, 加上字母\en{l}后(表示\en{local}), 也就是命令\en{lcd}, \en{lls}就是对本地操作. 命令\en{put}就是从本地上传文件, 如果想从远程下载文件就是使用命令\en{get}.
\par 
灵活使用 这两个命令即可在几分钟内把那个\en{WEB}应用在树莓派上跑起来.
\subsection{更多}
这两个命令非常强大, 下面列举了两个非常有用技巧我在这里就不细说了: 
\begin{itemize}
\item 使用证书替代输密码进行远程登陆验证, 免去反复输密码的痛苦.
\item 在远程登陆执行一条命令后自动登出, 不影响命令的远程运行.
\end{itemize} 
对于第二条我需要解释一下, 考虑如下情况, 使用\en{SSH}远程登陆到服务器上, 开始备份文件, 这是一个很漫长的过程, 如果你强行断开连接, 或者由于网络不稳定断开了连接, 那么备份也会相应终止, 很不方便. 第二条的意思就是实现登陆后在远程的本地执行命令, 这样登出或者是断开连接都和那个命令没有任何关系了.
\newpage
\end{CJK*}
\end{document}
